﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.SqlServer;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZSZ.DTO;
using ZSZ.IService;
using ZSZ.Model;

namespace ZSZ.Service
{
    public partial class HouseService : BaseService<House>, IHouseService
    {
        public IHouseAttachmentService houseAttachmentService { get; set; }
        private IQueryable<House> GetJoinAll()
        {
            return GetAll()
                .Include(h => h.HouseAttachments)
                .Include(h => h.HouseAttachments.Select(ha => ha.Attachment))
                .Include(h => h.Community)
                .Include(h => h.Community.Region)
                .Include(h => h.Community.Region.City)
                    .Include(h => h.DecorateStatus)
                    .Include(h => h.RoomType)
                    .Include(h => h.Status)
                    .Include(h => h.Type)
                    .Include(h => h.HousePics).AsNoTracking();
        }

        public HouseDTO[] GetPagedData(long cityId, long typeId, out long total, int pageIndex, int pageSize)
        {
            var entities = GetJoinAll().Where(h => h.Community.Region.CityId == cityId && h.TypeId == typeId);
            return base.GetPagedData(entities, out total, pageIndex, pageSize).ToList().Select(u => ToDTO(u)).ToArray();
        }

        public HouseDTO GetDTOById(long id)
        {
            var houes = GetJoinAll().Where(h => h.Id == id);
            int count = houes.Count();
            if (count <= 0)
            {
                return null;
            }
            else if (count == 1)
            {
                return ToDTO(houes.Single());
            }
            else
            {
                throw new ApplicationException("获取到多个 Id 为" + id + "的房源信息");
            }
        }

        public HouseDTO[] GetHouses()
        {
            return GetJoinAll().ToList().Select(h => ToDTO(h)).ToArray();
        }
        public HouseDTO[] GetHouses(long cityId, long typeId)
        {
            return GetJoinAll().Where(h => h.Community.Region.CityId == cityId && h.TypeId == typeId).ToList().Select(h => ToDTO(h)).ToArray();
        }

        public HouseDTO[] GetHousesByCityId(long cityId, int count)
        {
            return GetJoinAll().Where(h => h.Community.Region.CityId == cityId).OrderByDescending(h => h.HousePics.Count).ThenByDescending(h => h.Id).Take(count).ToList().Select(h => ToDTO(h)).ToArray();
        }

        public HouseDTO[] GetHousesByCommunityId(long communityId, int count)
        {
            return GetJoinAll().Where(h => h.CommunityId == communityId).OrderByDescending(h => h.HousePics.Count).ThenByDescending(h => h.Id).Take(count).ToList().Select(h => ToDTO(h)).ToArray();
        }

        public int GetTodayNewHouseCount(long cityId)
        {
                //房子创建的时间是在当前时间内的24个小时，就认为是“今天的房源”
                //日期相减结果是TimeSpan类型
                /*
                return GetAll().Count(h => h.Community.Region.CityId==cityId
                            && (DateTime.Now - h.CreateDateTime).TotalHours <= 24);*/
                /*
    DateTime date24HourAgo = DateTime.Now.AddHours(-24);//算出来一个24小时之前的时间
    return GetAll().Count(h => h.Community.Region.CityId == cityId
               && h.CreateDateTime<=date24HourAgo);*/
                return GetAll().Count(h => h.Community.Region.CityId == cityId
                           && SqlFunctions.DateDiff("hh", h.CreateDateTime, DateTime.Now) <= 24);
     
        }
        public HouseSearchResult Search(HouseSearchOptions options)
        {
            var items = GetJoinAll().Where(h => h.Community.Region.CityId == options.CityId
                        && h.TypeId == options.TypeId);
            if (options.RegionId != null)
            {
                items = items.Where(t => t.Community.RegionId == options.RegionId);
            }
            if (options.StartMonthRent != null)
            {
                items = items.Where(t => t.MonthRent >= options.StartMonthRent);
            }
            if (options.EndMonthRent != null)
            {
                items = items.Where(t => t.MonthRent <= options.EndMonthRent);
            }
            if (!string.IsNullOrEmpty(options.Keywords))
            {
                items = items.Where(t => t.Address.Contains(options.Keywords)
                        || t.Description.Contains(options.Keywords)
                        || t.Community.Name.Contains(options.Keywords)
                        || t.Community.Location.Contains(options.Keywords)
                        || t.Community.Traffic.Contains(options.Keywords));
            }
            long totalCount = items.LongCount();//总搜索结果条数

            switch (options.OrderByType)
            {
                case HouseSearchOrderByType.AreaAsc:
                    items = items.OrderBy(t => t.Area);
                    break;
                case HouseSearchOrderByType.AreaDesc:
                    items = items.OrderByDescending(t => t.Area);
                    break;
                case HouseSearchOrderByType.CreateDateDesc:
                    items = items.OrderByDescending(t => t.CreateDateTime);
                    break;
                case HouseSearchOrderByType.MonthRentAsc:
                    items = items.OrderBy(t => t.MonthRent);
                    break;
                case HouseSearchOrderByType.MonthRentDesc:
                    items = items.OrderByDescending(t => t.MonthRent);
                    break;
            }
            //一定不要items.Where
            //而要items=items.Where();
            //OrderBy要在Skip和Take之前
            //给用户看的页码从1开始，程序中是从0开始
            items = items.Skip((options.CurrentIndex - 1) * options.PageSize)
                .Take(options.PageSize);

            HouseSearchResult searchResult = new HouseSearchResult();
            searchResult.totalCount = totalCount;
            searchResult.result = items.ToList().Select(h => ToDTO(h)).ToArray();

            //List<HouseDTO> houses = new List<HouseDTO>();
            //foreach (var item in items)
            //{
            //    houses.Add(ToDTO(item));
            //}
            //searchResult.result = houses.ToArray();
            return searchResult;
        }

        private HouseDTO ToDTO(House entity)
        {
            HouseDTO dto = new HouseDTO();
            dto.CreateDateTime = entity.CreateDateTime;
            dto.Id = entity.Id;
            dto.Address = entity.Address;
            dto.Area = entity.Area;
            dto.AttachmentIds = entity.HouseAttachments.Select(ha => ha.Attachment.Id).ToArray();
            dto.CheckInDateTime = entity.CheckInDateTime;
            dto.CityId = entity.Community.Region.CityId;
            dto.CityName = entity.Community.Region.City.Name;
            dto.CommunityBuiltYear = entity.Community.BuiltYear;
            dto.CommunityId = entity.CommunityId;
            dto.CommunityLocation = entity.Community.Location;
            dto.CommunityName = entity.Community.Name;
            dto.CommunityTraffic = entity.Community.Traffic;
            dto.DecorateStatusId = entity.DecorateStatusId;
            dto.DecorateStatusName = entity.DecorateStatus.Name;
            dto.Description = entity.Description;
            dto.Direction = entity.Direction;
            var firstPic = entity.HousePics.FirstOrDefault(hp => hp.IsDeleted == false);
            if (firstPic != null)
            {
                dto.FirstThumbUrl = firstPic.ThumbUrl;
            }
            else
            {
                dto.FirstThumbUrl = "/upload/noPic.jpg";
            }
            dto.FloorIndex = entity.FloorIndex;
            dto.LookableDateTime = entity.LookableDateTime;
            dto.MonthRent = entity.MonthRent;
            dto.OwnerName = entity.OwnerName;
            dto.OwnerPhoneNum = entity.OwnerPhoneNum;
            dto.RegionId = entity.Community.RegionId;
            dto.RegionName = entity.Community.Region.Name;
            dto.RoomTypeId = entity.RoomTypeId;
            dto.RoomTypeName = entity.RoomType.Name;
            dto.StatusId = entity.StatusId;
            dto.StatusName = entity.Status.Name;
            dto.TotalFloorCount = entity.TotalFloorCount;
            dto.TypeId = entity.TypeId;
            dto.TypeName = entity.Type.Name;
            return dto;
        }

        public long Add(HouseDTO dto)
        {
            House entity = new House();
            entity.CommunityId = dto.CommunityId;
            entity.RoomTypeId = dto.RoomTypeId;
            entity.Address = dto.Address;
            entity.MonthRent = dto.MonthRent;
            entity.StatusId = dto.StatusId;
            entity.Area = dto.Area;
            entity.DecorateStatusId = dto.DecorateStatusId;
            entity.TotalFloorCount = dto.TotalFloorCount;
            entity.FloorIndex = dto.FloorIndex;
            entity.TypeId = dto.TypeId;
            entity.Direction = dto.Direction;
            entity.LookableDateTime = dto.LookableDateTime;
            entity.CheckInDateTime = dto.CheckInDateTime;
            entity.OwnerName = dto.OwnerName;
            entity.OwnerPhoneNum = dto.OwnerPhoneNum;
            entity.Description = dto.Description;
            long houseId = Add(entity).Id;

            //配套设施
            houseAttachmentService.Add(houseId, dto.AttachmentIds);

            return houseId;
        }

        public void Update(HouseDTO dto)
        {
            House entity = GetById(dto.Id);
            if (entity == null)
            {
                throw new Exception("获取不到房源(id:" + dto.Id + ")信息");
            }
            entity.CommunityId = dto.CommunityId;
            entity.RoomTypeId = dto.RoomTypeId;
            entity.Address = dto.Address;
            entity.MonthRent = dto.MonthRent;
            entity.StatusId = dto.StatusId;
            entity.Area = dto.Area;
            entity.DecorateStatusId = dto.DecorateStatusId;
            entity.TotalFloorCount = dto.TotalFloorCount;
            entity.FloorIndex = dto.FloorIndex;
            entity.TypeId = dto.TypeId;
            entity.Direction = dto.Direction;
            entity.LookableDateTime = dto.LookableDateTime;
            entity.CheckInDateTime = dto.CheckInDateTime;
            entity.OwnerName = dto.OwnerName;
            entity.OwnerPhoneNum = dto.OwnerPhoneNum;
            entity.Description = dto.Description;
            Update(entity);

            //配套设施
            houseAttachmentService.Update(dto.Id, dto.AttachmentIds);
        }
    }
}
